// 1.3.1 指针-其他概念-Null 指针

/**
 * 
 * 学习 C++ 的指针既简单又有趣。通过指针，可以简化一些 C++ 编程任务的执行，还有一些任务，如动态内存分配，没有指针是无法执行的。所以，想要成为一名优秀的 C++ 程序员，学习指针是很有必要的。
 * 正如您所知道的，每一个变量都有一个内存位置，每一个内存位置都定义了可使用连字号（&）运算符访问的地址，它表示了在内存中的一个地址。请看下面的实例，它将输出定义的变量地址：
 * 
 * ------------------
 * 其他概念
 * 在 C++ 中，有很多指针相关的概念，这些概念都很简单，但是都很重要。下面列出了 C++ 程序员必须清楚的一些与指针相关的重要概念：
 * 
 * 1. C++ Null 指针
 * C++ 支持空指针。NULL 指针是一个定义在标准库中的值为零的常量。
 * 
 * 2. C++ 指针的算术运算
 * 可以对指针进行四种算术运算：++、--、+、-
 * 
 * 3. C++ 指针 vs 数组
 * 指针和数组之间有着密切的关系。
 * 
 * 4. C++ 指针数组
 * 可以定义用来存储指针的数组。
 * 
 * 5. C++ 指向指针的指针
 * C++ 允许指向指针的指针。
 * 
 * 6. C++ 传递指针给函数
 * 通过引用或地址传递参数，使传递的参数在调用函数中被改变。
 * 
 * 7. C++ 从函数返回指针
 * C++ 允许函数返回指针到局部变量、静态变量和动态内存分配。
 * 
 * ~~~~~~~~~~~~~~~~~~~~
 * Null 指针
 * 在变量声明的时候，如果没有确切的地址可以赋值，为指针变量赋一个 NULL 值是一个良好的编程习惯。赋为 NULL 值的指针被称为空指针。
 * NULL 指针是一个定义在标准库中的值为零的常量。请看下面的程序：
 * 
 * 
 * 在大多数的操作系统上，程序不允许访问地址为 0 的内存，因为该内存是操作系统保留的。然而，内存地址 0 有特别重要的意义，它表明该指针不指向一个可访问的内存位置。但按照惯例，如果指针包含空值（零值），则假定它不指向任何东西。
 * 
 * 如需检查一个空指针，您可以使用 if 语句，如下所示：
 * 
 * 因此，如果所有未使用的指针都被赋予空值，同时避免使用空指针，就可以防止误用一个未初始化的指针。很多时候，未初始化的变量存有一些垃圾值，导致程序难以调试。
*/

#include <iostream>

int main(void)
{
  int *ptr = NULL;
  std::cout << "ptr: " << ptr << std::endl; // 0
  // std::cout << "*ptr: " << *ptr << std::endl;// 终止程序，c++不允许访问地址为空的内存

  if (ptr)
  {
    std::cout << "ptr不为空" << std::endl;
  }

  if (!ptr)
  {
    std::cout << "ptr为空" << std::endl;
  }

  /**
   * 空指针不提倡使用NULL来表示，
   * C++11标准后，用nullptr来表示空指针。
  */

  ptr = nullptr;
  std::cout << "ptr: " << ptr << std::endl;   // 0
  // std::cout << "*ptr: " << *ptr << std::endl; // 终止程序

  printf("-------------end--------------\n");
  return 0;
}